package com.kanavi.stand.controller;

import cn.hutool.extra.spring.SpringUtil;
import com.kanavi.stand.entity.MyThread;
import com.kanavi.stand.entity.UserStandInfo;
import com.kanavi.stand.mapper.UserStandInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.expression.spel.ast.NullLiteral;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author tanghailan
 * @date 2020-10-22 17:54
 */
@RestController
@Slf4j
//@Transactional
public class TransactionTestController {

    @Resource
    private UserStandInfoMapper standInfoMapper;
    @Resource
    private MyThread thread;

    @Autowired
    private PlatformTransactionManager transactionManager;

    List<TransactionStatus> transactionStatuses = Collections
        .synchronizedList(new ArrayList<TransactionStatus>());

    @GetMapping("test")
    public String test() {
        log.info("test");
        UserStandInfo userStandInfo = new UserStandInfo().
            setStandCountDate(11L).
            setStandCountTotal(112L).
//                setUserId("22").
    setCreateTime(new Date());
//        UserStandInfo userStandInfo2 = new UserStandInfo().
//                setStandCountDate(11L).
//                setStandCountTotal(112L).
//                setUserId("11").
//        setCreateTime(null);
//        this.standInfoMapper.insert(userStandInfo2);
        try {
            this.standInfoMapper.insert(userStandInfo);
        } catch (Exception e) {
            e.printStackTrace();
        }
//        thread.start();

        try {
            new Thread(() -> {
                // 使用这种方式将事务状态都放在同一个事务里面
                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                // 事物隔离级别，开启新事务，这样会比较安全些。
                def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
                // 获得事务状态
                TransactionStatus status = transactionManager.getTransaction(def);
                //强制手动把每个线程的事务状态放到一个同步集合里面。然后如果有单个异常，循环回滚每个线程。
                transactionStatuses.add(status);

                UserStandInfo userStandInfo1 = new UserStandInfo().
                    setStandCountDate(11L).
                    setStandCountTotal(112L).
                    setUserId("22").
                    setCreateTime(new Date());
                this.standInfoMapper.insert(userStandInfo1);
                transactionManager.commit(status);

                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                log.info("11111111122=================");
            }).start();
        } catch (Exception e) {
            log.error("###线程异常");
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        log.info("主线程结束11111111122=================");
        return "";
    }
}
